import { Application } from 'egg'
import { CommonData } from '../common-data'
import { constData, jsonData } from './data'

const defaultCompare = (existsRecord, newRecord) => {
  if (existsRecord) return existsRecord.id === newRecord.id
  return existsRecord.id === newRecord.id
}

const nameCompare = (existsRecord, newRecord) => {
  if (existsRecord) return existsRecord.name === newRecord.name
  return existsRecord.name === newRecord.name
}

// const codeCompare = (existsRecord, newRecord) => {
//   if (existsRecord) return existsRecord.code === newRecord.code
//   return existsRecord.code === newRecord.code
// }

const createEntities = async (app: Application, repositoryName: string
  , entities: Array<{ [key: string]: any }>, comparePredicate?: (existsRecord, newRecord) => {}) => {
  if (!entities) {
    app.logger.info(`seed createEntities ${repositoryName} error: entities null.`)
    return null
  }
  if (!entities.length) return []

  const compare = comparePredicate || defaultCompare
  const existsEntities = await app.uow[repositoryName].all()
  const promises = [] as any[]
  for (const entity of entities) {
    if (!existsEntities.find(data => compare(data, entity))) {
      promises.push(app.uow[repositoryName].create(entity))
    }
  }
  if (promises.length) {
    app.logger.info(`seed ${repositoryName} ${promises.length}/${entities.length} exists ${existsEntities.length}.`)
  }
  return Promise.all(promises)
}

const seedIsolatedTable = async (app: Application) => {
  await createEntities(app, 'City', constData.City, nameCompare)
  await createEntities(app, 'Setting', constData.Setting, nameCompare)
  // await createEntities(app, 'User', constData.User)
  for (const user of constData.User) {
    await app.uow.auth.createUser(user)
  }
}

const seedAssociatedTable = async (app: Application) => {
  //
}

const seedSettingsByCommonData = async (app: Application) => {
  const settings: any[] = []
  Object.keys(CommonData).forEach(key => {
    if (key !== 'toArray') {
      settings.push({
        name: key,
        value: CommonData[key],
      })
    }
  })
  // sequelize 的 null 和 js 的 null 不相等
  // tslint:disable-next-line triple-equals
  await createEntities(app, 'Setting', settings, (r, d) => r.name === d.name && r.userId == d.userId)
}

export default async (app: Application) => {
  app.logger.info('app/core/seed/seed.js seeding...')
  await seedIsolatedTable(app)
  await seedAssociatedTable(app)

  await seedSettingsByCommonData(app)

  // await seedPO(app)

  if (Object.keys(jsonData).length) {
    app.logger.info('unseed json data', Object.keys(jsonData))
  }
  app.logger.info('app/core/seed/seed.js seeded')
}
